package org.apache.catalina.startup;

import java.util.EnumSet;
import java.util.Locale;

import javax.servlet.DispatcherType;
import javax.servlet.MultipartConfigElement;

import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterInfoDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.apache.tomcat.util.descriptor.web.MultipartDef;
import org.apache.tomcat.util.descriptor.web.ServletDef;
import org.apache.tomcat.util.descriptor.web.ServletInfoDef;
import org.apache.tomcat.util.descriptor.web.ServletMappingDef;

import com.github.netty.protocol.servlet.ServletContext;
import com.github.netty.protocol.servlet.ServletFilterRegistration;
import com.github.netty.protocol.servlet.ServletRegistration;

final class ServletContextUtil {
	private ServletContextUtil() {
	}

	static void set(ServletInfoDef source, ServletContext dest) {
		ServletDef sd = source.getServlet();
		ServletMappingDef smd = source.getServletMapping();
		ServletRegistration sr = dest.addServlet(sd.getServletName(), sd.getServletClass());
		sr.addMapping(smd.getUrlPatterns().stream().toArray(String[]::new));

		sr.setAsyncSupported(sd.getAsyncSupported());
		if (sd.getParameterMap() != null && sd.getParameterMap().size() > 0) {
			sr.setInitParameters(sd.getParameterMap());
		}
		if (sd.getLoadOnStartup() != null) {
			sr.setLoadOnStartup(sd.getLoadOnStartup());
		}
		if (sd.getRunAs() != null && sd.getRunAs().length() > 0) {
			sr.setRunAsRole(sd.getRunAs());
		}
//		MultipartConfig
		MultipartDef md = sd.getMultipartDef();
		if (md != null) {
			long maxFileSize = -1;
			long maxRequestSize = -1;
			int fileSizeThreshold = 0;

			if (null != md.getMaxFileSize()) {
				maxFileSize = Long.parseLong(md.getMaxFileSize());
			}
			if (null != md.getMaxRequestSize()) {
				maxRequestSize = Long.parseLong(md.getMaxRequestSize());
			}
			if (null != md.getFileSizeThreshold()) {
				fileSizeThreshold = Integer.parseInt(md.getFileSizeThreshold());
			}
			MultipartConfigElement mce = new MultipartConfigElement(md.getLocation(), maxFileSize, maxRequestSize,
					fileSizeThreshold);
			sr.setMultipartConfig(mce);
		}
//		ServletSecurity
	}

	static void set(FilterInfoDef source, ServletContext dest) {
		FilterDef fd = source.getFilterDef();
		FilterMap fm = source.getFilterMap();
		ServletFilterRegistration sr = dest.addFilter(fd.getFilterName(), fd.getFilterClass());
		String[] dispatcherNames = fm.getDispatcherNames();
		EnumSet<DispatcherType> es = EnumSet.noneOf(DispatcherType.class);
		for (String d : dispatcherNames) {
			String dispatcher = d.toUpperCase(Locale.ENGLISH);

			if (dispatcher.equals(DispatcherType.FORWARD.name())) {
				es.add(DispatcherType.FORWARD);
			} else if (dispatcher.equals(DispatcherType.INCLUDE.name())) {
				// apply INCLUDE to the global dispatcherMapping.
				es.add(DispatcherType.INCLUDE);
			} else if (dispatcher.equals(DispatcherType.REQUEST.name())) {
				// apply REQUEST to the global dispatcherMapping.
				es.add(DispatcherType.REQUEST);
			} else if (dispatcher.equals(DispatcherType.ERROR.name())) {
				// apply ERROR to the global dispatcherMapping.
				es.add(DispatcherType.ERROR);
			} else if (dispatcher.equals(DispatcherType.ASYNC.name())) {
				// apply ERROR to the global dispatcherMapping.
				es.add(DispatcherType.ASYNC);
			}
		}
		if (es.size() > 0) {
			sr.addMappingForUrlPatterns(es, fm.getMatchAllUrlPatterns(), fm.getURLPatterns());
		}
		if (fd.getParameterMap() != null && fd.getParameterMap().size() > 0) {
			sr.setInitParameters(fd.getParameterMap());
		}
		if (fd.getAsyncSupportedBoolean()) {
			sr.setAsyncSupported(fd.getAsyncSupportedBoolean());
		}
		
	}

}
